#ifndef _EEFS_H_
#define _EEFS_H_

#include "stdint.h"
#include "driver.h"
#include "eefs_port.h"

#define FILE_ID_TRANSMITER (EE_MAX_FILES-1)

typedef struct t_EeFile{
   uint16_t m_fileId;     ///< file number
   uint8_t  m_mode;
   uint16_t m_size;
   uint16_t m_pos;        ///< file position
   uint16_t m_offs;       ///< offset in block
   uint16_t m_currBlk;  ///< block id
   char block_data[EE_BLOCK_SIZE-sizeof(EeBlockId) ];    ///< block cache
} __attribute__((packed)) EeFile;

typedef struct t_DirEnt{
	EeBlockId  listHead;
	uint16_t size:12;
	uint16_t typ:4;
}__attribute__((packed)) DirEnt;

typedef struct t_EeFat{
	uint16_t  version;
	uint16_t  mySize;
	EeBlockId  freeListHead;
	uint16_t  bs;
	DirEnt   files[EE_MAX_FILES];
}__attribute__((packed)) EeFat;


#define EE_OK 0
#define EE_ERR_TMO 1
#define EE_ERR_FULL 2
#define EE_ERR_FAIL 3
#define EE_MODE_READ (1)
#define EE_MODE_WRITE (2)

class EeFs
{
public:
    EeFs(Driver *driver =0);
    ~EeFs();
       
    int open(EeFile *fd, uint8_t fileId, uint8_t mode);
    int read(EeFile *fd, void *buffer, unsigned int len, unsigned int offset);
    int write(EeFile *fd, void *buffer, unsigned int len, unsigned int offset);
    int readRLE(EeFile *fd, void *buffer, unsigned int len, unsigned int offset);
    int writeRLE(EeFile *fd, void *buffer, unsigned int len, unsigned int offset);
    char checkSum(void *buffer, int len);
    int flush(EeFile *fd);
    int close(EeFile *fd);
    int rm(EeFile *fd);

    int format();
    int check();


    EeBlockId blockAlloc();
    void blockFree(EeBlockId block);
    void setLink(EeBlockId block, EeBlockId next_block);
    EeBlockId getLink(EeBlockId block);
    void setFreeList(EeBlockId freeList);
    void setFileList(uint16_t fileId, EeBlockId startBlock);

    void operator delete(void *t){ port_free(t);}
    void *operator new(unsigned int len){ return port_malloc(len);}
private:
    Driver *driver;
    EeFat eeFat;
};


#endif


